package com.ruoyi.web.controller.device;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.gg.reader.api.dal.*;
import com.gg.reader.api.protocol.gx.*;
import com.ruoyi.base.domain.BaseMatGroup;
import com.ruoyi.base.domain.BaseTrayMat;
import com.ruoyi.base.service.IBaseMatGroupService;
import com.ruoyi.base.service.IBaseTrayMatService;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.OrderNoUtil;
import com.ruoyi.framework.config.GlobalConfig;
import com.ruoyi.system.domain.TbDevice;
import com.ruoyi.system.domain.TbEpcRecord;
import com.ruoyi.system.service.ITbDeviceService;
import com.ruoyi.system.service.ITbEpcRecordService;
import com.ruoyi.web.controller.tcp.ReadEPCGpiInOutNewD01;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.ArrayList;
import java.util.List;


@Component
public class MyApplicationListener  {

    @Autowired
    private TransactionTemplate transactionTemplate;

    @Autowired
    private ITbDeviceService iTbDeviceService;

    @Autowired
    private ITbEpcRecordService iTbEpcRecordService;

    @Autowired
    private IBaseMatGroupService baseMatGroupService;

    @Autowired
    private IBaseTrayMatService baseTrayMatService;

    @EventListener
    public void handleApplicationReady(ApplicationReadyEvent event) {
        GServer server = new GServer();
        // TODO: 首先通过[读写器管理软件]设置设备为客户端模式 ip为上位机ip 端口为所要监听的端口
        if (server.open(8160)) {
            subscribeServerHandler(server);
            System.out.println("开始监听");
        } else {
            System.out.println("监听失败");
        }
    }

    //订阅监听上报
    public  void subscribeServerHandler(GServer server) {
        server.onGClientConnected = new HandlerGClientConnected() {
            @Override
            public void log(GClient gClient, String serialNumber) {
                LambdaQueryWrapper<TbDevice> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                String s = gClient.getName().split(":")[0];
                lambdaQueryWrapper.like(TbDevice::getDeviceIps, s);
                System.out.println(iTbDeviceService);
                TbDevice one = iTbDeviceService.getOne(lambdaQueryWrapper);
                if (one==null) {
                    TbDevice tbDevice = new TbDevice();
                    tbDevice.setDeviceIps(gClient.getName());
                    tbDevice.setCreateTime((DateUtils.getNowDate()));
                    tbDevice.setDeviceOnline(1);
                    iTbDeviceService.save(tbDevice);
                }else {
                    one.setDeviceOnline(1);
                    iTbDeviceService.saveOrUpdate(one);
                }


                subscribeHandler(gClient);
                System.out.println(gClient.getName() + "大哥成功");
                MsgAppSetBeep msgAppSetBeep = new MsgAppSetBeep();
                msgAppSetBeep.setBeepStatus(1);
                gClient.sendSynMsg(msgAppSetBeep);
                if(0==msgAppSetBeep.getRtCode()){
                    System.out.println("已开启");
                }else{
                    System.out.println("蜂鸣器关闭失败");
                }
                gClient.setSendHeartBeat(true);//开启心跳检测Tcp连接状态
                gClient.setPrint(true);
                subscribeTcpHandler(gClient);//订阅Tcp断连上报

                testStop(gClient);//测试监听成功的连接是否通信正常
            }
        };
    }

    //订阅TCP断开连接上报
    private  void subscribeTcpHandler(final GClient client) {
        client.onDisconnected = new HandlerTcpDisconnected() {
            @Override
            public void log(String s) {
                LambdaQueryWrapper<TbDevice> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                String s1= s.split(":")[0];
                lambdaQueryWrapper.like(TbDevice::getDeviceIps, s1);
                TbDevice one = iTbDeviceService.getOne(lambdaQueryWrapper);
                one.setDeviceOnline(0);
                iTbDeviceService.saveOrUpdate(one);
                System.out.println("连接" + s + "已断开");
                client.close();//释放当前连接资源
            }
        };
    }

    private  void testStop(GClient client) {
        MsgBaseStop msg = new MsgBaseStop();
        client.sendSynMsg(msg);
        if (0x00 == msg.getRtCode()) {
            System.out.println("Stop success");
        } else {
            System.out.println(msg.getRtMsg());
        }


    }

    // 订阅gpi触发上报
    public  void subscribeHandler(GClient client) {
        client.onGpiStart = new HandlerGpiStart() {
            public void log(String s, LogAppGpiStart logAppGpiStart) {
                // 索引从0开始
                if (null != logAppGpiStart) {
                    System.out.println(logAppGpiStart);
                }
            }
        };

        client.onGpiOver = new HandlerGpiOver() {
            public void log(String s, LogAppGpiOver logAppGpiOver) {
                if (null != logAppGpiOver) {
                    System.out.println(logAppGpiOver);
                }
            }
        };
//        String orderNo = OrderNoUtil.getOutOrderNo("EPC");
//        LambdaQueryWrapper<TbDevice> lambdaQueryWrapper = new LambdaQueryWrapper<>();
//        String s1= client.getName().split(":")[0];
//        lambdaQueryWrapper.like(TbDevice::getDeviceIps, s1);
//        TbDevice one = iTbDeviceService.getOne(lambdaQueryWrapper);
//        List<TbEpcRecord> tbEpcRecords = new ArrayList<>();
        // 订阅标签上报事件
        client.onTagEpcLog = new HandlerTagEpcLog() {

            @Override
            public void log(String readName, final LogBaseEpcInfo logBaseEpcInfo) {

                LambdaQueryWrapper<TbDevice> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                String s1= client.getName().split(":")[0];
                lambdaQueryWrapper.like(TbDevice::getDeviceIps, s1);
                TbDevice one = iTbDeviceService.getOne(lambdaQueryWrapper);
                List<TbEpcRecord> tbEpcRecords = new ArrayList<>();

                // 回调内部如有阻塞，会影响API正常使用
                // 标签回调数量较多，请将标签数据先缓存起来再作业务处理
                if (null != logBaseEpcInfo && 0 == logBaseEpcInfo.getResult()) {
                    String orderNo = OrderNoUtil.getOutOrderNo("EPC");
                    //数据打印
                    if (logBaseEpcInfo.getCykeoRule()== 153) {
                        TbEpcRecord tbEpcRecord = new TbEpcRecord();
                        tbEpcRecord.setDeviceId(one.getId());
                        tbEpcRecord.setEpcOrder(orderNo);
                        tbEpcRecord.setEpcNum(logBaseEpcInfo.getEpc());
                        tbEpcRecord.setIsEnter(0);
                        tbEpcRecords.add(tbEpcRecord);

//							System.out.println("由GPI1先触发后开始读取的，即方向为 GPI1->GPI2。");
                        System.out.println("设备"+readName +"。方向进——" + logBaseEpcInfo);
                    } else if (logBaseEpcInfo.getCykeoRule()==154) {
//                        LambdaQueryWrapper<TbDevice> lambdaQueryWrapper = new LambdaQueryWrapper<>();
//                        String s1= readName.split(":")[0];
//                        lambdaQueryWrapper.like(TbDevice::getDeviceIps, s1);
//                        TbDevice one = iTbDeviceService.getOne(lambdaQueryWrapper);
//                        String orderNo = OrderNoUtil.getOutOrderNo("EPC");


                        TbEpcRecord tbEpcRecord = new TbEpcRecord();
                        tbEpcRecord.setDeviceId(one.getId());
                        tbEpcRecord.setEpcOrder(orderNo);
                        tbEpcRecord.setEpcNum(hexToString(logBaseEpcInfo.getEpc()));
                        tbEpcRecord.setIsEnter(1);
                        tbEpcRecords.add(tbEpcRecord);
//                        Boolean aBoolean = transactionTemplate.execute(e -> {
//                            iTbEpcRecordService.saveBatch(tbEpcRecords);
//                            return Boolean.TRUE;
//                        });
//							System.out.println("由GPI2先触发后开始读取的，即方向为 GPI2->GPI1。");
                        System.out.println("设备"+readName +"。方向出——" + logBaseEpcInfo);

                        if(GlobalConfig.urgencyStatus==1){
                            if(tbEpcRecord.getEpcNum().startsWith("HP")){
                                LambdaQueryWrapper<BaseMatGroup> lqw = new LambdaQueryWrapper<>();
                                lqw.eq(BaseMatGroup::getGroupNum,tbEpcRecord.getEpcNum());
                                BaseMatGroup baseMatGroup  = baseMatGroupService.getOne(lqw);
                                if(ObjectUtil.isNotNull(baseMatGroup)&&baseMatGroup.getStatus()!=3){
                                    System.out.println("出库"+baseMatGroup);
                                    baseMatGroup.setStatus(3);
                                    baseMatGroupService.updateById(baseMatGroup);

                                    LambdaQueryWrapper<BaseTrayMat> lqw1 = new LambdaQueryWrapper<>();
                                    lqw1.eq(BaseTrayMat::getBomId,baseMatGroup.getBomId());
                                    lqw1.eq(BaseTrayMat::getMatId,baseMatGroup.getTargetId());
                                    BaseTrayMat baseTrayMat = baseTrayMatService.getOne(lqw1);
                                    baseTrayMat.setNum(baseTrayMat.getNum()-1);
                                    baseTrayMatService.updateById(baseTrayMat);
                                }
                            }
                        }
                    }
                }
                Boolean aBoolean = transactionTemplate.execute(e -> {
                    iTbEpcRecordService.saveBatch(tbEpcRecords);
                    return Boolean.TRUE;
                });
            }
        };

        client.onTagEpcOver = new HandlerTagEpcOver() {
            @Override
            public void log(String readName, LogBaseEpcOver logBaseEpcOver) {
                if (null != logBaseEpcOver) {
                    System.out.println("Epc log over.");
                }
            }
        };

    }
    public static String hexToString(String hex) {
        StringBuilder output = new StringBuilder();
        for (int i = 0; i < hex.length(); i += 2) {
            String str = hex.substring(i, i + 2);
            output.append((char) Integer.parseInt(str, 16));
        }
        return output.toString();
    }
}
